package com.dabai.iot.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dabai.common.core.exception.ServiceException;
import com.dabai.common.core.utils.ObjectUtils;
import com.dabai.common.core.utils.StringUtils;
import com.dabai.common.mybatis.core.page.TableDataInfo;
import com.dabai.iot.common.enums.TopicSourceType;
import com.dabai.iot.core.entity.ProductEntity;
import com.dabai.iot.core.entity.ProductTopicEntity;
import com.dabai.iot.core.mapper.ProductTopicMapper;
import com.dabai.iot.core.service.IProductService;
import com.dabai.iot.core.service.IProductTopicService;
import com.dabai.iot.mqtt.topics.SysTopics;
import com.dabai.iot.mqtt.topics.TopicDefinition;
import com.dabai.iot.mqtt.topics.TopicDirection;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 消息主题 Service 实现类
 *
 * @author kev1n
 */
@Service
@RequiredArgsConstructor
public class ProductTopicServiceImpl extends ServiceImpl<ProductTopicMapper, ProductTopicEntity> implements IProductTopicService {

    private final IProductService productService;

    @Override
    public boolean addTopic(ProductTopicEntity productTopic) {
        // 设备订阅主题必须符合规则
        if (TopicDirection.SUB.getValue().equals(productTopic.getTopicDirection())) {
            if (!productTopic.getTopic().contains(SysTopics.DEVICE_SN)) {
                throw new ServiceException("主题格式不正确");
            }
        }

        // 校验同一产品下自定义主题是否重复
        if (checkTopicDuplicate(productTopic)) {
            throw new ServiceException("已经存在相同的主题");
        }

        // 自定义 Topic
        productTopic.setTopicSourceType(TopicSourceType.custom.getValue());
        return save(productTopic);
    }

    @Override
    public boolean updateTopic(ProductTopicEntity productTopic) {
        return updateById(productTopic);
    }

    /**
     * 校验同一产品下自定义主题是否重复
     */
    boolean checkTopicDuplicate(ProductTopicEntity topic) {
        return this.lambdaQuery()
            .eq(ProductTopicEntity::getProductId, topic.getProductId())
            .eq(ProductTopicEntity::getTopic, topic.getTopic())
            .ne(ObjectUtils.isNotNull(topic.getId()), ProductTopicEntity::getId, topic.getId())
            .exists();
    }

    @Override
    public boolean removeTopic(Long id) {
        return removeById(id);
    }

    @Override
    public List<ProductTopicEntity> selectList(@NonNull Long productId, String topicSourceType, String topicDirection) {
        if (TopicSourceType.system.getValue().equals(topicSourceType)) {
            // 系统主题
            return sysTopics(productId);

        } else {
            // 自定义主题
            return lambdaQuery()
                .eq(ProductTopicEntity::getProductId, productId)
                .eq(ProductTopicEntity::getTopicSourceType, TopicSourceType.custom.getValue())
                .eq(StringUtils.isNotBlank(topicDirection), ProductTopicEntity::getTopicDirection, topicDirection)
                .orderByDesc(ProductTopicEntity::getCreateTime)
                .list();
        }
    }

    @Override
    public TableDataInfo<ProductTopicEntity> selectPage(IPage<ProductTopicEntity> page, Long productId, String topicSourceType, String topicDirection) {
        if (TopicSourceType.system.getValue().equals(topicSourceType)) {
            // 系统主题
            List<ProductTopicEntity> sysTopics = sysTopics(productId);
            return TableDataInfo.build(sysTopics);
        } else {
            QueryWrapper<ProductTopicEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                .eq(ProductTopicEntity::getProductId, productId)
                .eq(StringUtils.isNotBlank(topicSourceType), ProductTopicEntity::getTopicSourceType, topicSourceType)
                .eq(StringUtils.isNotBlank(topicDirection), ProductTopicEntity::getTopicDirection, topicDirection)
                .orderByDesc(ProductTopicEntity::getCreateTime);
            return TableDataInfo.build(this.page(page, queryWrapper));
        }
    }

    /**
     * 获取系统主题
     */
    private List<ProductTopicEntity> sysTopics(Long productId) {
        ProductEntity product = productService.getProductCacheById(productId);
        if (product == null) {
            return List.of();
        }

        List<ProductTopicEntity> sysTopics = new ArrayList<>();
        List<TopicDefinition> defaultSysTopics = SysTopics.getDefaultSysTopics();

        int sort = 1;
        for (TopicDefinition definition : defaultSysTopics) {
            ProductTopicEntity sysTopic = new ProductTopicEntity();
            sysTopic.setProductId(product.getId());
            sysTopic.setTenantId(product.getTenantId());
            sysTopic.setTopic(definition.template().replaceAll(SysTopics.PRODUCT_KEY_ESCAPE, product.getProductKey()));
            sysTopic.setTopicSourceType(TopicSourceType.system.getValue());
            sysTopic.setTopicDirection(definition.direction().getValue());
            sysTopic.setTopicDesc(definition.description());
            sysTopic.setSort(sort);
            sysTopic.setUpdateTime(product.getUpdateTime());
            sort++;
            sysTopics.add(sysTopic);
        }

        return sysTopics;
    }

}
